package com.suxin.time;

import lombok.extern.slf4j.Slf4j;

import java.io.Closeable;
import java.io.IOException;
import java.util.function.Supplier;

/**
 * @Author: tang
 * @Description:
 * @Date 2025/1/8 10:58
 */
@Slf4j
public class TimeTracker implements Closeable {

    private final String operationName;

    private final boolean logEnabled;

    private final long startTime;

    public TimeTracker(String operationName) {
        this(operationName, true);
    }

    public TimeTracker(String operationName, boolean logEnabled) {
        this.operationName = operationName;
        this.logEnabled = logEnabled;
        this.startTime = System.nanoTime();
        if (this.logEnabled) {
            log.info("开始执行: {}%n", this.operationName);
        }
    }

    public static TimeTracker of(String operationName) {
        return new TimeTracker(operationName);
    }

    /**
     * 不抛出异常。
     * @param operationName
     * @param supplier
     * @return
     * @param <T>
     */
    public static <T> T track(String operationName, Supplier<T> supplier) {
        try {
            return trackThrow(operationName, supplier);
        } catch (Exception e) {
            log.error("业务异常!",e);
        }
        return null;
    }

    /**
     * 跟踪带返回值的代码块执行时间，允许抛出异常。
     * @param operationName
     * @param supplier
     * @return
     * @param <T>
     * @throws Exception
     */
    public static <T> T trackThrow(String operationName, Supplier<T> supplier) throws Exception{
        try (TimeTracker timeTracker = of(operationName)){
            return supplier.get();
        }
    }



    @Override
    public void close() throws IOException {
        if(logEnabled) {
            // 计算执行时间（转换为毫秒）
            long timeElapsed = (System.nanoTime() - startTime) / 1_000_000;
            log.info("{} 执行完成，耗时: {} ms %n", operationName, timeElapsed);
        }
    }
}
